package com.vivid.system.controller;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.vivid.system.domain.Model;
import com.vivid.system.service.IModelService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.vivid.system.domain.Prediction;
import com.vivid.system.service.IPredictionService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 预测表Controller
 *
 * @author vivid
 * @date 2022-08-09
 */
@CrossOrigin
@RestController
@RequestMapping("/system/prediction")
public class PredictionController extends BaseController
{
    @Autowired
    private IPredictionService predictionService;
    @Autowired
    private ToolController toolController;
    @Autowired
    private IModelService modelService;
    private File file;
    /**
     * 查询预测表列表
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:list')")
    @GetMapping("/list")
    public TableDataInfo list(Prediction prediction)
    {
        List<Prediction> list = predictionService.selectPredictionList(prediction);
        return getDataTable(list);
    }

    /**
     * 导出预测表列表
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:export')")
    @Log(title = "预测表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Prediction prediction)
    {
        List<Prediction> list = predictionService.selectPredictionList(prediction);
        ExcelUtil<Prediction> util = new ExcelUtil<Prediction>(Prediction.class);
        util.exportExcel(response, list, "预测表数据");
    }

    /**
     * 获取预测表详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:query')")
    @GetMapping(value = "/{predictionId}")
    public AjaxResult getInfo(@PathVariable("predictionId") Long predictionId)
    {
        return AjaxResult.success(predictionService.selectPredictionByPredictionId(predictionId));
    }

    /**
     * 新增预测表
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:add')")
    @Log(title = "预测表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Prediction prediction)
    {
        return toAjax(predictionService.insertPrediction(prediction));
    }

    /**
     * 修改预测表
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:edit')")
    @Log(title = "预测表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Prediction prediction)
    {
        return toAjax(predictionService.updatePrediction(prediction));
    }

    /**
     * 删除预测表
     */
    @PreAuthorize("@ss.hasPermi('system:prediction:remove')")
    @Log(title = "预测表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{predictionIds}")
    public AjaxResult remove(@PathVariable Long[] predictionIds)
    {
        return toAjax(predictionService.deletePredictionByPredictionIds(predictionIds));
    }
    /**
     * 接收上传的文件
     * 将MultipartFile转换为File
     */
    @PostMapping("/file")
    public AjaxResult MultipartFile(MultipartFile multipartFile) {
        //判断是否为null
        if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
            return AjaxResult.error("文件为空，请重新上传！");
        }
        this.file = toolController.MultipartFile(multipartFile);
        return AjaxResult.success("上传成功！");
    }

    /**
     * 预测
     */
    @PostMapping("/predict")
    public List predict(@RequestParam String modelName, HttpSession session){
        List resultList = new ArrayList();
        String path = this.file.getAbsolutePath();//获取上传文件绝对路径
        String predictionResultPath = this.selectPredictionPath(modelName,path);//预测结果文件存放的路径
        Model model = modelService.selectModelByModelName(modelName);
        //要将模型存放路径发给python
        try {
            String[] args1 = new String[] { "python", "python-code\\predict.py", model.getModelPath(),path,predictionResultPath};
            Process proc = Runtime.getRuntime().exec(args1);// 执行py文件
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream(),"gb2312"));
            String line = null;
            Prediction prediction = new Prediction();
            while ((line = in.readLine()) != null) {
                prediction.setPredictionFilePath(line);
                prediction.setPredictionTime(new java.util.Date());
                prediction.setModelName(modelName);
                prediction.setUserId((Long) session.getAttribute("userId"));
                predictionService.insertPrediction(prediction);
                resultList.add(modelName);
                resultList.add(readTxt(line));
                return resultList;
            }

            in.close();
            proc.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取历史数据
     */
    @GetMapping("/showHistory")
    public List showHistory(HttpSession session){
        List resultList = new ArrayList();
        List<Prediction> predictionList = predictionService.selectPredictionByUserId((Long) session.getAttribute("userId"));
        for(Prediction pre : predictionList){
            resultList.add(pre.getPredictionTime());
            resultList.add(pre.getModelName());
            resultList.add(readTxt(pre.getPredictionFilePath()));
        }
        return resultList;
}

    /**
     * 读取txt文件
     */
    public List readTxt(String filePath) {
        List lis = new ArrayList<>();
        try {
            File myFile = new File(filePath);//通过字符串创建File类型对象，指向该字符串路径下的文件
            if (myFile.isFile() && myFile.exists()) { //判断文件是否存在
                InputStreamReader Reader = new InputStreamReader(new FileInputStream(myFile), "UTF-8");
                BufferedReader bufferedReader = new BufferedReader(Reader);
                String lineTxt = null;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    //buffereReader.readLine()按行读取写成字符串
                    lis.add(stringSplit(lineTxt));
                }
                Reader.close();
            } else {
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
        return lis;
    }
    /**
     * 分割字符串，以逗号为准
     * return float类型的集合
     */
    public  List stringSplit(String str) throws ParseException {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //用于格式化成 年月日时分秒
        List lis = new ArrayList<>();
        if(str.indexOf(",") != -1){
            String[] split = str.split(",");
            for (int i = 0; i < split.length; i++) {
                String url = split[i];
                if(i==0){
                    lis.add(url);//年月日时分秒
                }
                else{
                    lis.add(Float.parseFloat(url));
                }

            }
        }else if(str.indexOf("，") != -1){
            String[] split = str.split("，");
            for (int i = 0; i < split.length; i++) {
                String url = split[i];
                if(i==0){
                    lis.add(url);//年月日时分秒
                }
                else{
                    lis.add(Float.parseFloat(url));
                }
            }
        }else{
            String[] split = str.split(",");
            for (int i = 0; i < split.length; i++) {
                String url = split[i];
                if(i==0){
                    lis.add(url);//年月日时分秒
                }
                else{
                    lis.add(Float.parseFloat(url));
                }
            }
        }
        return lis;
    }

    /**
     * 对预测表预测结果文件路径查重，返回预测文件结果路径
     */
    public String selectPredictionPath(String modelName,String path){
        //假设上传文件为predict.txt,模型名为model,预测文件结果最后部分为predict_model.txt
        //需先对结果路径进行查重
        Prediction pre = new Prediction();
        pre.setModelName(modelName);
        int size = predictionService.selectPredictionList(pre).size();//该模型名的预测数据有几条
        String result = path;
        result = result.replace(".txt","_"+modelName+".txt");
        if(size>0){//数据库已有重复路径
            String newPath = result.replace(".txt",String.valueOf(size+1)+".txt");
            return newPath;
        }
        return result;
    }

}
